package industry;

import java.util.Random;

import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerItemConsumeEvent;
import org.bukkit.inventory.ItemStack;

import actives.ActiveManager;
import actives.ActiveType;

import skills.Skill;
import skills.Skills;
import skills.SkillHandler;

public class Farming extends Skill {
	
	public Farming(Player player, int level, int exp) {
		super(player, level, exp);
	}

	@Override
	public void info() {
		super.info();
		message(1, "Work in progress");
		message(250, "Passive: " + level/10 + "% chance for double drop");
		message(250, "Level 250 Passive: Crops grow faster");
		message(750, "Level 750 Passive: Extra food value from crops.");
	}
	
	public static void active(Player player, Block block) {
		switch (ActiveManager.getState(player, ActiveType.FARMING)) {
		case PRIMED:
			ActiveManager.activate(player, ActiveType.FARMING, null);
			break;
		case ACTIVE:
			block.breakNaturally();
			break;
		default:
			break;
		}
	}
	
	@EventHandler
	private void blockBreak(BlockBreakEvent event) {
		Player player = event.getPlayer();
		Block block = event.getBlock();
		if (isCrop(block)) {
			if (isGrown(block)) {
				Skill farming = SkillHandler.getSkill(player, Skills.FARMING);
				farming.addExp(getExp(block));
				double chance = farming.level() / 10;
				boolean proc = new Random().nextDouble() <= chance;
				if (proc) {
					World world = block.getWorld();
					Location location = block.getLocation();
					for(ItemStack drop : block.getDrops()) {
						world.dropItemNaturally(location, drop);
					}
				}
			}			
		}
	}
	
	@EventHandler
	private void blockPlace(BlockPlaceEvent event) {
		Player player = event.getPlayer();
		int level = SkillHandler.getSkill(player, Skills.FARMING).level();
		if (level >= 250) {
			Block block = event.getBlock();
			switch (block.getType()) {
			case CROPS:
			case CARROT:
			case POTATO:
				block.setData((byte) 7);
				break;
			case NETHER_WARTS:
				block.setData((byte) 3);
				break;
			default:
				break;
			}
			
		}
	}

	@EventHandler
	private void itemConsume(PlayerItemConsumeEvent event) {
		Player player = event.getPlayer();
		int level = SkillHandler.getSkill(player, Skills.FARMING).level();
		if (level >= 750) {
			ItemStack food = event.getItem();
			int hunger = player.getFoodLevel();
			float saturation = player.getSaturation();
			switch (food.getType()) {
			case CARROT_ITEM:
				player.setFoodLevel(hunger + 4);
				player.setSaturation(saturation + 4.8f);
				break;
			case POTATO_ITEM:
				player.setFoodLevel(hunger + 1);
				player.setSaturation(saturation + 0.6f);
				break;
			case BREAD:
				player.setFoodLevel(hunger + 5);
				player.setSaturation(saturation + 6f);
				break;
			default:
				break;			
			}
		}
	}
	
	public static boolean isCrop(Block block) {
		switch (block.getType()) {
		case CROPS:
		case NETHER_WARTS:
		case POTATO:
		case CARROT:
			return isGrown(block);
		case PUMPKIN:
		case MELON_BLOCK:		
		case SUGAR_CANE_BLOCK:
		case CACTUS:		
			return true;
		default:
			return false;
		}
	}

	public static boolean isGrown(Block block) {
		switch (block.getType()) {
		case CROPS:
		case POTATO:
		case CARROT:
			return block.getData() == 7;
		case NETHER_WARTS:
			return block.getData() == 3;
		default:
			return true;
		}
	}
	
	private int getExp(Block block) {
		switch (block.getType()) {
		case CROPS:
		case POTATO:
		case CARROT:
		case NETHER_WARTS:
		case MELON_BLOCK:
		case PUMPKIN:
			return 10;
		case CACTUS:
			return 10 * checkBlocks(block, Material.CACTUS);
		case SUGAR_CANE_BLOCK:
			return 5 * checkBlocks(block, Material.SUGAR_CANE_BLOCK);
		default:
			return 0;
		}
	}
	
	private int checkBlocks(Block block, Material material) {
		if (block.getType().equals(material)) {
			return 1 + checkBlocks(block.getRelative(0, 1, 0), material);
		}
		return 0;
	}
}
